package com.framework.service.common.impl;

import com.framework.common.model.response.R;
import com.framework.common.util.cache.CacheUtil;
import com.framework.common.util.cache.SpringCacheKeyGenerator;
import com.framework.common.util.other.NumeralUtil;
import com.framework.common.util.redis.RedisKeyUtil;
import com.framework.mapper.common.TypeMapper;
import com.framework.model.common.vo.TypeVo;
import com.framework.model.system.SystemUser;
import com.framework.model.system.vo.SystemUserVo;
import com.framework.service.base.BaseService;
import com.framework.service.common.TypeService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;

/**
 * @author 龘鵺
 * @version 1.0
 * @className com.framework.service.common.impl.TypeServiceImpl
 * @description 公共类型业务接口实现类
 * @datetime 2024-04-20 14:57:12
 */
@Service("typeServiceImpl")
public class TypeServiceImpl extends BaseService implements TypeService {
    private Logger log = LoggerFactory.getLogger(TypeServiceImpl.class);
    @Autowired
    private TypeMapper typeMapper;

    /**
     * @param id 编号
     * @return com.framework.model.common.vo.TypeVo
     * @author 龘鵺
     * @title 公共根据编号查询数据
     * @description 公共根据编号查询数据
     * @datetime 2024-04-20 14:57:12
     */
    @Override
    public TypeVo selectByPrimaryKey(Long id) {
        TypeVo row = typeMapper.selectByPrimaryKey(id);
        if (row == null) {
            row = new TypeVo();
        }
        return row;
    }

    /**
     * @param id 1 编号
     * @return com.framework.model.common.vo.TypeVo
     * @title 根据编号查询公共类型
     * @description 根据编号查询公共类型
     * @author 龘鵺
     * @datetime 2024-04-20 14:57:12
     * @version 1.0
     */
    @Override
    public TypeVo getByIdParam(Long id) {
        TypeVo row = new TypeVo();
        row.setId(id);
        row.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ONE);
        TypeVo p = typeMapper.selectByParam(row);
        return p;
    }

    /**
     * @param id             1 编号
     * @param parentTypeCode 2 上级代码
     * @return com.framework.model.common.vo.TypeVo
     * @title 查询公共类型
     * @description 查询公共类型
     * @author 龘鵺
     * @datetime 2025-01-09 11:11:11
     */
    @Override
    public TypeVo getByIdParam(Long id, String parentTypeCode) {
        TypeVo row = new TypeVo();
        row.setId(id);
        row.setParentTypeCode(parentTypeCode);
        row.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ONE);
        TypeVo p = typeMapper.selectByParam(row);
        return p;
    }

    /**
     * @param id             1 编号
     * @param parentTypeCode 2 上级类型代码
     * @return com.framework.common.model.response.R
     * @title 根据编号, 上级类型代码查询信息
     * @description 根据编号, 上级类型代码查询信息
     * @author 龘鵺
     * @datetime 2025-01-09 11:11:11
     */
    @Override
    public R<?> getByIdInfo(Long id, String parentTypeCode) {
        TypeVo type = new TypeVo();
        type.setId(id);
        type.setParentTypeCode(parentTypeCode);
        type.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ONE);
        type = typeMapper.selectByParam(type);
        return R.ok(type);
    }

    /**
     * @param row 1 公共类型类
     * @return com.framework.common.model.response.R
     * @title 新增公共类型
     * @description 新增公共类型
     * @author 龘鵺
     * @datetime 2024-04-20 14:57:12
     * @version 1.0
     */
    @Override
    @Transactional
    @CacheEvict(value = CacheUtil.CACHE_SUFFIX + "type", allEntries = true)
    public R<?> save(TypeVo row) {
        TypeVo param = new TypeVo();
        param.setTypeCode(row.getTypeCode());
        param.setParentTypeCode(row.getParentTypeCode());
        int num = typeMapper.isExist(param);
        if (num > NumeralUtil.POSITIVE_ZERO) {
            return R.fail("类型代码已存在!");
        }
        if (StringUtils.isNotEmpty(row.getParentTypeCode())) {
            param = new TypeVo();
            param.setTypeCode(row.getParentTypeCode());
            num = typeMapper.findPageListCount(param);
            if (num == NumeralUtil.POSITIVE_ZERO) {
                return R.fail("上级类型错误!");
            }
            param = new TypeVo();
            param.setTypeValue(row.getTypeValue());
            param.setParentTypeCode(row.getParentTypeCode());
            num = typeMapper.isExist(param);
            if (num > NumeralUtil.POSITIVE_ZERO) {
                return R.fail("类型数值已存在!");
            }
        }

        Long userId = getUserId();
        Date date = new Date();
        row.setOperaterTime(date);
        row.setCreateId(userId);
        row.setOperaterId(userId);
        row.setCreateTime(date);
        row.setOperaterStatus(NumeralUtil.POSITIVE_ONE);
        typeMapper.insertSelective(row);
        return R.ok();
    }

    /**
     * @param row 1 公共类型类
     * @return com.framework.common.model.response.R
     * @title 编辑公共类型
     * @description 编辑公共类型
     * @author 龘鵺
     * @datetime 2024-04-20 14:57:12
     * @version 1.0
     */
    @Override
    @Transactional
    @CacheEvict(value = CacheUtil.CACHE_SUFFIX + "type", allEntries = true)
    public R<?> edit(TypeVo row) {
        TypeVo queryParam = typeMapper.selectByPrimaryKey(row.getId());
        if (queryParam == null) {
            return R.fail("编辑信息不存在!");
        }
        TypeVo param = new TypeVo();
        param.setId(row.getId());
        param.setTypeCode(row.getTypeCode());
        param.setParentTypeCode(row.getParentTypeCode());
        int num = typeMapper.isExist(param);
        if (num > NumeralUtil.POSITIVE_ZERO) {
            return R.fail("类型代码已存在!");
        }
        SystemUser systemUser = getUser();
        Long userId = systemUser.getId();
        Date date = new Date();
        if (StringUtils.isNotEmpty(row.getParentTypeCode())) {
            param = new TypeVo();
            param.setTypeCode(row.getParentTypeCode());
            num = typeMapper.findPageListCount(param);
            if (num == NumeralUtil.POSITIVE_ZERO) {
                return R.fail("上级类型错误!");
            }
            param = new TypeVo();
            param.setId(row.getId());
            param.setTypeValue(row.getTypeValue());
            param.setParentTypeCode(row.getParentTypeCode());
            num = typeMapper.isExist(param);
            if (num > NumeralUtil.POSITIVE_ZERO) {
                return R.fail("类型数值已存在!");
            }
        }
        if (StringUtils.isEmpty(row.getParentTypeCode()) && !queryParam.getTypeCode().equals(row.getTypeCode())) {
            TypeVo type = new TypeVo();
            type.setParentTypeCode(queryParam.getTypeCode());
            int count = typeMapper.findPageListCount(type);
            //上级类型代码变动后，修改子项类型的上级类型代码
            if (count > NumeralUtil.POSITIVE_ZERO) {
                type.setOperaterStatus(NumeralUtil.POSITIVE_TWO);
                type.setOperaterId(userId);
                type.setOperaterTime(date);
                type.setTypeCode(queryParam.getTypeCode());
                type.setParentTypeCode(row.getTypeCode());
                typeMapper.updateByParentTypeCode(type);
            }
        }

        row.setOperaterStatus(NumeralUtil.POSITIVE_TWO);
        row.setOperaterId(userId);
        row.setOperaterTime(date);
        typeMapper.updateByPrimaryKeySelective(row);
        return R.ok();
    }

    /**
     * @param id 1 编号
     * @return com.framework.common.model.response.R
     * @title 删除公共类型
     * @description 删除公共类型
     * @author 龘鵺
     * @datetime 2024-04-20 14:57:12
     * @version 1.0
     */
    @Override
    @Transactional
    @CacheEvict(value = CacheUtil.CACHE_SUFFIX + "type", allEntries = true)
    public R<?> delete(Long id, String parentTypeCode) {
        TypeVo row = new TypeVo();
        SystemUser systemUser = getUser();
        Long userId = systemUser.getId();
        Date date = new Date();
        row.setId(id);
        row.setParentTypeCode(parentTypeCode);
        row.setOperaterTime(date);
        row.setOperaterId(userId);
        row.setOperaterStatus(NumeralUtil.NEGATIVE_ONE);
        typeMapper.delete(row);
        return R.ok();
    }

    /**
     * @param idList 1 编号集合
     * @return com.framework.common.model.response.R
     * @title 批量删除公共类型
     * @description 批量删除公共类型
     * @author 龘鵺
     * @datetime 2024-04-20 14:57:12
     * @version 1.0
     */
    @Override
    @Transactional
    @CacheEvict(value = CacheUtil.CACHE_SUFFIX + "type", allEntries = true)
    public R<?> batchDeleteList(List<Long> idList, String parentTypeCode) {
        TypeVo row = new TypeVo();
        row.setIdList(idList);
        row.setParentTypeCode(parentTypeCode);
        List<TypeVo> list = typeMapper.findByList(row);
        String[] delKey = new String[list.size()];
        for (int i = NumeralUtil.POSITIVE_ZERO; i < list.size(); i++) {
            delKey[i] = RedisKeyUtil.getPermissionButtonKey(list.get(i).getTypeCode());
        }
        SystemUser systemUser = getUser();
        Long userId = systemUser.getId();
        Date date = new Date();
        row.setOperaterStatus(NumeralUtil.NEGATIVE_ONE);
        row.setOperaterTime(date);
        row.setOperaterId(userId);
        typeMapper.deleteList(row);

//        TypeVo row = new TypeVo();
//        SystemUser systemUser = getUser();
//        Long userId = systemUser.getId();
//        Date date = new Date();
//        row.setIdList(idList);
//        row.setOperaterTime(date);
//        row.setOperaterId(userId);
//        row.setOperaterStatus(NumeralUtil.NEGATIVE_ONE);
//        //typeMapper.deleteList(row);
        return R.ok();
    }

    /**
     * @param row 1 公共类型类
     * @return java.util.List<com.framework.model.common.vo.TypeVo>
     * @title 查询公共类型集合
     * @description 查询公共类型集合
     * @author 龘鵺
     * @datetime 2024-04-20 14:57:12
     * @version 1.0
     */
    @Override
    public List<TypeVo> findByList(TypeVo row) {
        row.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ONE);
        List<TypeVo> list = typeMapper.findByList(row);
        return list;
    }

    /**
     * @param row  1 公共类型类
     * @param type 2 查询类型，0=上级，  1=下级
     * @return com.framework.common.model.response.R
     * @title 分页查询公共类型列表
     * @description 分页查询公共类型列表
     * @author 龘鵺
     * @datetime 2024-04-20 14:57:12
     * @version 1.0
     */
    @Override
    public R<?> findParamPageList(TypeVo row, int type) {
        if (type == NumeralUtil.POSITIVE_ZERO) {
            row.setParentTypeCode("");
        }
        row.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ONE);
        int count = typeMapper.findPageListCount(row);
        if (count == NumeralUtil.POSITIVE_ZERO) {
            return R.ok();
        }
        List<TypeVo> list = typeMapper.findPageList(row);
        return R.ok(list, count);
    }

    /**
     * @param parentTypeCode 1 上级类型代码
     * @return com.framework.model.common.vo.TypeVo
     * @title 根据上级类型代码查询信息
     * @description 根据上级类型代码查询信息
     * @author 龘鵺
     * @datetime 2022-01-09 11:11:11
     */
    @Override
    public TypeVo getByParentTypeCodeInfo(String parentTypeCode) {
        TypeVo type = new TypeVo();
        type.setTypeCode(parentTypeCode);
        type.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ONE);
        type = typeMapper.selectByParam(type);
        if (type == null) {
            type = new TypeVo();
        }
        return type;
    }

    /**
     * @param parentTypeCode 1 上级类型代码
     * @return java.util.List<com.framework.model.common.vo.TypeVo>
     * @title 根据上级类型代码查询类型
     * @description 根据上级类型代码查询类型
     * @author 龘鵺
     * @datetime 2025-01-09 11:11:11
     */
    @Override
    @Cacheable(value = CacheUtil.CACHE_SUFFIX + "type", keyGenerator = SpringCacheKeyGenerator.KEYGENERATOR, unless = "#result == null")
    public List<TypeVo> findByParentCodeList(String parentTypeCode) {
        TypeVo row = new TypeVo();
        row.setParentTypeCode(parentTypeCode);
        row.setEnableStatus(NumeralUtil.POSITIVE_ONE);
        row.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ZERO);
        List<TypeVo> list = typeMapper.findByParentCodeList(row);
        return list;
    }

    /**
     * @param parentTypeCode 1 上级类型代码
     * @return com.framework.common.model.response.R
     * @title 根据上级类型代码查询类型
     * @description 根据上级类型代码查询类型
     * @author 龘鵺
     * @datetime 2025-01-09 11:11:11
     */
    @Override
    @Cacheable(value = CacheUtil.CACHE_SUFFIX + "type", keyGenerator = SpringCacheKeyGenerator.KEYGENERATOR, unless = "#result == null")
    public R<?> findByParentCodeListTwo(String parentTypeCode) {
        TypeVo row = new TypeVo();
        row.setParentTypeCode(parentTypeCode);
        row.setEnableStatus(NumeralUtil.POSITIVE_ONE);
        row.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ZERO);
        List<TypeVo> list = typeMapper.findByParentCodeList(row);
        return R.ok(list);
    }

    /**
     * @param id             1 编号
     * @param parentTypeCode 2 上级编码
     * @return com.framework.common.model.response.R
     * @title 启用禁用方法
     * @description 启用禁用方法
     * @author 龘鵺
     * @datetime 2024-06-20 20:28:00
     */
    @Override
    @CacheEvict(value = CacheUtil.CACHE_SUFFIX + "type", allEntries = true)
    public R<?> enable(Long id, String parentTypeCode) {
        String timeKey = RedisKeyUtil.getObjKey("TYPE_ENABLE_KEY", "TYPE_ENABLE_KEY", id.toString());
        long expireNum = redisUtil.getExpire(timeKey);
        if (expireNum > NumeralUtil.POSITIVE_ZERO) {
            return R.fail("操作频繁,请" + expireNum + "秒后重试!");
        }
        TypeVo queryParam = new TypeVo();
        SystemUserVo systemUserVo = getUser();
        queryParam.setId(id);
        queryParam.setParentTypeCode(parentTypeCode);
        queryParam = typeMapper.selectByParam(queryParam);
        if (queryParam == null) {
            return R.fail("信息不存在!");
        }
        redisUtil.setString(timeKey, NumeralUtil.STRING_POSITIVE_ZERO, NumeralUtil.POSITIVE_FIFTEEN);
        Long userId = systemUserVo.getId();
        Date date = new Date();
        TypeVo row = new TypeVo();
        row.setOperaterId(userId);
        row.setOperaterTime(date);
        row.setOperaterStatus(NumeralUtil.POSITIVE_ONE);
        row.setId(id);
        row.setEnableStatus(queryParam.getEnableStatus().intValue() == NumeralUtil.POSITIVE_TWO ? NumeralUtil.POSITIVE_ONE : NumeralUtil.POSITIVE_TWO);
        row.setParentTypeCode(parentTypeCode);
        typeMapper.updateByIdAndParentTypeCode(row);
        return R.ok();
    }
}